home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 127 / PC Guia 127.iso / Software / Utils / Forecastfox / Bin / forecastfox-0.8.5.1-fx+mz+ns.xpi / components / ffDisk.js next >
Encoding:
Text File  |  2006-02-18  |  17.4 KB  |  542 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Forecastfox.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Jon Stritar <jstritar@MIT.EDU>.
  18.  * Portions created by the Initial Developer are Copyright (C) 2005
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  * Jon Stritar <jstritar@MIT.EDU>
  23.  * Richard Klein <richwklein@mchsi.com>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. const CLASS_ID = Components.ID("{E39B9B47-0B40-4b61-958E-EA509AA2DF5C}");
  40. const CLASS_NAME = "Forecastfox Disk I/O";
  41. const CONTRACT_ID = "@ensolis.com/forecastfox/disk;1";
  42. const ffIDisk = Components.interfaces.ffIDisk;
  43. const nsIFile = Components.interfaces.nsIFile;
  44.  
  45. /******************************************************************************
  46.  * ffDisk component
  47.  ******************************************************************************/
  48. function ffDisk() {};
  49. ffDisk.prototype = {
  50.   _cache: null,
  51.   _icons: null,
  52.   _temp: null,
  53.   _defaults: null,
  54.   _transforms: null,  
  55.   _weatherfox: null,
  56.   _errors: null,
  57.   _foStream: null,
  58.   _fiStream: null,
  59.   _siStream: null,
  60.   _serializer: null,
  61.   _parser: null,
  62.     
  63.   start: function()
  64.   {
  65.     var dirs = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
  66.     var app = dirs.get("XCurProcD", Components.interfaces.nsIFile);
  67.     var profile = dirs.get("ProfD", Components.interfaces.nsIFile);
  68.     var install;
  69.     
  70.     //get temp directory        
  71.     this._temp = dirs.get("TmpD", Components.interfaces.nsIFile);
  72.     
  73.     //use extension manager to figure out install location
  74.     try {
  75.       var em = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);    
  76.       install = em.getItemLocation("{0538E3E3-7E9B-4d49-8831-A227C80A7AD3}");
  77.     } catch (e) {
  78.       install = profile.clone();
  79.       install.append("extensions");
  80.       install.append("{0538E3E3-7E9B-4d49-8831-A227C80A7AD3}");
  81.       
  82.       if (!install.exists()) {
  83.         install = this._app.clone(); 
  84.         install.append("extensions");
  85.         install.append("{0538E3E3-7E9B-4d49-8831-A227C80A7AD3}");
  86.       };
  87.     };
  88.  
  89.     //get default and transform locations
  90.     this._defaults = install.clone();
  91.     this._defaults.append("defaults");
  92.     this._transforms = this._defaults.clone();
  93.     this._transforms.append("transforms");
  94.   
  95.     //get our cache directory
  96.     this._cache = this._ensureDirectory(profile, "forecastfox");
  97.     
  98.     //get errors directory
  99.     this._errors = this._ensureDirectory(this._cache, "errors");
  100.     
  101.     //get our icons directory
  102.     this._icons = this._ensureDirectory(this._cache, "icons");
  103.     
  104.     //get weatherfox directory
  105.     this._weatherfox = profile.clone();
  106.     this._weatherfox.append("weatherfox");
  107.     
  108.     //setup stream components
  109.     this._foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);     
  110.     this._fiStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
  111.     this._siStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  112.     this._serializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Components.interfaces.nsIDOMSerializer);
  113.     this._parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);       
  114.   },
  115.   
  116.   stop: function()
  117.   {
  118.     this._cache = null;
  119.     this._icons = null;
  120.     this._temp = null;
  121.     this._defaults = null;
  122.     this._transforms = null;  
  123.     this._weatherfox = null;    
  124.     this._foStream = null;
  125.     this._fiStream = null;
  126.     this._siStream = null;
  127.     this._serializer = null;
  128.     this._parser = null;
  129.     this._errors = null;
  130.   },
  131.   
  132.   get: function(aName, aType)
  133.   {
  134.     var file = null;
  135.     switch (aType) {
  136.       case ffIDisk.TYPE_CACHE:
  137.       default:
  138.         file = this._cache.clone();
  139.         break;
  140.       case ffIDisk.TYPE_ICONS:
  141.         file = this._icons.clone();
  142.         break;
  143.       case ffIDisk.TYPE_TEMP:
  144.         file = this._temp.clone();
  145.         break;
  146.       case ffIDisk.TYPE_WEATHERFOX:
  147.         file = this._weatherfox.clone();
  148.         break;
  149.       case ffIDisk.TYPE_DEFAULTS:
  150.         file = this._defaults.clone();
  151.         break;
  152.       case ffIDisk.TYPE_TRANSFORMS:
  153.         file = this._transforms.clone();
  154.         break;
  155.       case ffIDisk.TYPE_ERRORS:
  156.         file = this._errors.clone();
  157.     };
  158.   
  159.     file.append(aName);
  160.     if (aType == ffIDisk.TYPE_TEMP)
  161.       file.createUnique(nsIFile.NORMAL_FILE_TYPE, 0664);                     
  162.     return file;
  163.   },
  164.   
  165.   move: function(aFrom, aTo)
  166.   {
  167.     // first move to a unique name
  168.     var temp = this.get(aTo.leafName, ffIDisk.TYPE_TEMP);
  169.     aFrom.moveTo(temp.parent, temp.leafName);
  170.     
  171.     // now move to the new name
  172.     temp.moveTo(aTo.parent, aTo.leafName);
  173.   },
  174.   
  175.   copy: function(aFrom, aTo)
  176.   {
  177.     //remove to file
  178.     if (aTo.exists())
  179.       aTo.remove(false);
  180.       
  181.     //copy from file
  182.     aFrom.copyTo(aTo.parent, aTo.leafName);  
  183.   },
  184.   
  185.   getFileURI: function(aFile)
  186.   {
  187.     var ios = Components.classes["@mozilla.org/network/io-service;1"].createInstance(Components.interfaces.nsIIOService);
  188.     var uri = ios.newFileURI(aFile);
  189.     return uri.spec;
  190.   },
  191.   
  192.   recordFile: function(aFile)
  193.   {
  194.     var file = this.get("", ffIDisk.TYPE_ERRORS);
  195.     var name = aFile.leafName;
  196.     if (name.indexOf(".") == -1)
  197.       name = name + "-err";
  198.     else {
  199.       var ind = name.indexOf(".");
  200.       var ext = name.substring(ind, name.length);
  201.       name = name.substring(0, ind);
  202.       name = name + "-err" + ext;
  203.     }
  204.     
  205.     file.append(name);
  206.     file.createUnique(nsIFile.NORMAL_FILE_TYPE, 0664);
  207.     this.copy(aFile, file);
  208.     
  209.     //log the error
  210.     this.recordMessage("Message: Error file (" + file.leafName + ") created for "+aFile.leafName+".");
  211.   },
  212.   
  213.   recordMessage: function(aMessage)
  214.   {
  215.     // get the error log file
  216.     var file = this.get("errors.log", ffIDisk.TYPE_ERRORS);
  217.     
  218.     // append the new log entry
  219.     var msg = new Date() + ": " + aMessage + "\r\n";
  220.     this._writeString(file, msg, true);
  221.   },
  222.   
  223.   recordError: function(aMessage, aError)
  224.   {
  225.     //write message
  226.     this.recordMessage(aMessage);
  227.     
  228.     //write error
  229.     this.recordMessage("Exception: " + aError.toString());
  230.     
  231.     //write call stack
  232.     var frame = aError.location;
  233.     while (frame) {
  234.       this.recordMessage("Stack: " + frame.toString());
  235.       frame = frame.caller;
  236.     };
  237.   },
  238.   
  239.   clear: function(aType, aCache)
  240.   {
  241.     //just get a folder
  242.     var folder = this.get("", aType);
  243.     if (!folder.exists())
  244.       return;
  245.       
  246.     //make sure its a directory
  247.     if (!folder.isDirectory())
  248.       return;
  249.       
  250.     //get list of files
  251.     var entries = folder.directoryEntries;
  252.     while (entries.hasMoreElements()) {
  253.       var entry = entries.getNext();
  254.       entry = entry.QueryInterface(Components.interfaces.nsIFile);
  255.       var name = entry.leafName;
  256.       
  257.       if (aCache) {
  258.         //remove cache files      
  259.         if (name.indexOf("cache") != -1) {
  260.           if (entry.isDirectory())
  261.             entry.remove(true);
  262.           else
  263.             entry.remove(false);
  264.         };
  265.       } else {
  266.         //remove all files
  267.         if (entry.isDirectory())
  268.           entry.remove(true);
  269.         else
  270.           entry.remove(false);      
  271.       };
  272.     }                
  273.   },
  274.   
  275.   remove: function(aType)
  276.   {
  277.     //just get a folder
  278.     var folder = this.get("", aType);
  279.     if (!folder.exists())
  280.       return;
  281.       
  282.     //make sure its a directory
  283.     if (!folder.isDirectory())
  284.       return;
  285.       
  286.     folder.remove(true);
  287.   },
  288.   
  289.   read: function(aFile)
  290.   {
  291.     //load document into string variable    
  292.     var charset = "UTF-8";  
  293.     var contents = new String();    
  294.     this._fiStream.init(aFile, 1, 0, false);
  295.     
  296.     try {      
  297.       var is = Components.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(Components.interfaces.nsIConverterInputStream);
  298.       is.init(this._fiStream, charset, 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);  
  299.       var str = {};
  300.       while (is.readString(this._fiStream.available(), str) != 0) {
  301.         contents += str.value;
  302.       };
  303.     } catch(e) {
  304.       var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  305.       converter.charset = charset;
  306.       this._siStream.init(this._fiStream);
  307.       while (this._siStream.available() > 0) {
  308.         var chunk = this._siStream.read(this._siStream.available());
  309.         contents += converter.ConvertToUnicode(chunk);      
  310.       };
  311.       this._siStream.close();                      
  312.     };
  313.  
  314.     //close file
  315.     this._fiStream.close();
  316.     
  317.     //convert string to DOM
  318.     //  XXX watch for strange window errors here when modal windows popup on startup
  319.     var doc = this._parser.parseFromString(contents, "text/xml");
  320.     return doc;  
  321.   },
  322.   
  323.   write: function(aDoc, aFile, aBackup)
  324.   {  
  325.     //create a temporary file
  326.     var temp = null;
  327.     if (aFile.parent != this._temp)
  328.       temp = this.get(aFile.leafName, ffIDisk.TYPE_TEMP);
  329.     else
  330.       temp = aFile;
  331.       
  332.     //convert the document to a string
  333.     var content = this._serializer.serializeToString(aDoc);
  334.           
  335.     //initialize file stream
  336.     var flags = 0x02 | 0x08 | 0x20;
  337.     var charset = "UTF-8";    
  338.     var os = null;
  339.     this._foStream.init(temp, flags, 0664, 0);  
  340.          
  341.     try {
  342.       //try converter stream
  343.       os = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream);      
  344.       os.init(this._foStream, charset, 0, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  345.       os.writeString(content);
  346.       os.close;
  347.     } catch(e) {
  348.       //use string converter
  349.       var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  350.       converter.charset = charset;
  351.       var chunk = converter.ConvertFromUnicode(content);
  352.       this._foStream.write(chunk, chunk.length);
  353.       var fin = converter.Finish();
  354.       if (fin.length > 0)
  355.         this._foStream.write(fin, fin.length);
  356.     };
  357.     
  358.     //close file stream
  359.     this._foStream.close();    
  360.     
  361.     //create a backup
  362.     if (aBackup) {
  363.       var name = aFile.leafName;
  364.       var ext = name.substring(name.lastIndexOf(".") + 1, name.length);
  365.       name = name.replace(ext, "bak");
  366.       var backup = aFile.parent.clone();
  367.       backup.append(name);
  368.       this.copy(temp, backup);
  369.     };
  370.           
  371.     //move temp to correct location
  372.     if (aFile.parent != this._temp)
  373.       this.move(temp, aFile);
  374.   },
  375.   
  376.   valid: function(aDoc)
  377.   {
  378.     //object passed
  379.     if(!aDoc)
  380.       return false;
  381.       
  382.     //parser error
  383.     if (aDoc.childNodes[0].localName == "parsererror")
  384.       return false;
  385.         
  386.     return true;
  387.   },
  388.   
  389.   _ensureDirectory: function(aParent, aName)
  390.   {
  391.     var file = aParent.clone();
  392.     file.append(aName);
  393.     
  394.     if (!file.exists())
  395.       file.create(file.DIRECTORY_TYPE, 0755);
  396.  
  397.     if (!file.isDirectory()) {
  398.       file.remove(false);
  399.       file.create(file.DIRECTORY_TYPE, 0755);
  400.     };
  401.     
  402.     //make sure we can read and write to and from the directory
  403.     if (!file.isReadable() || !file.isWritable())
  404.       file.permissions = 0755;
  405.     
  406.     return file;
  407.   },
  408.   
  409.   _writeString: function(aFile, aString, aAppend)
  410.   {
  411.     //load document into string variable    
  412.     var charset = "UTF-8";  
  413.     var contents = new String();    
  414.     var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  415.     converter.charset = charset;
  416.         
  417.     // if we're appending, read in the old stuff
  418.     if (aAppend && aFile.exists() && aFile.isReadable()) {
  419.     
  420.       //load document into string variable  
  421.       this._fiStream.init(aFile, 1, 0, false);
  422.       try {      
  423.         var is = Components.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(Components.interfaces.nsIConverterInputStream);
  424.         is.init(this._fiStream, charset, 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);  
  425.         var str = {};
  426.         while (is.readString(this._fiStream.available(), str) != 0) {
  427.           contents += str.value;
  428.         };
  429.       } catch(e) {
  430.         this._siStream.init(this._fiStream);
  431.         while (this._siStream.available() > 0) {
  432.           var chunk = this._siStream.read(this._siStream.available());
  433.           contents += converter.ConvertToUnicode(chunk);      
  434.         };
  435.         this._siStream.close();                      
  436.       };
  437.       
  438.       //close file
  439.       this._fiStream.close();
  440.     };
  441.     
  442.     contents = contents + converter.ConvertToUnicode(aString);
  443.           
  444.     //initialize file stream
  445.     var flags = 0x02 | 0x08 | 0x20;
  446.     var os = null;
  447.     this._foStream.init(aFile, flags, 0664, 0);  
  448.          
  449.     try {
  450.       //try converter stream
  451.       os = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream);      
  452.       os.init(this._foStream, charset, 0, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  453.       os.writeString(contents);
  454.       os.close;
  455.     } catch(e) {
  456.       //use string converter
  457.       var chunk = converter.ConvertFromUnicode(contents);
  458.       this._foStream.write(chunk, chunk.length);
  459.       var fin = converter.Finish();
  460.       if (fin.length > 0)
  461.         this._foStream.write(fin, fin.length);
  462.     };
  463.     
  464.     //close file stream
  465.     this._foStream.close();        
  466.   },
  467.      
  468.   ///////////////////////////
  469.   // nsIClassInfo  
  470.   getInterfaces: function(aCount)
  471.   {
  472.     var ifaces = new Array();
  473.     ifaces.push(Components.interfaces.ffIDisk);
  474.     ifaces.push(Components.interfaces.nsIClassInfo);
  475.     ifaces.push(Components.interfaces.nsISupports);
  476.     aCount.value = ifaces.length;
  477.     return ifaces;
  478.   },
  479.   
  480.   getHelperForLanguage: function(aLanguage) { return null; },
  481.   get contractID() { return CONTRACT_ID; },
  482.   get classID() { return CLASS_ID; },
  483.   get classDescription() { return CLASS_NAME; },
  484.   get implementationLanguage() { return Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT; },
  485.   get flags() { return Components.interfaces.nsIClassInfo.SINGLETON; },
  486.          
  487.   ///////////////////////////
  488.   // nsISupports
  489.   QueryInterface: function (aIID)
  490.   {
  491.     if (!aIID.equals(Components.interfaces.ffIDisk) &&
  492.         !aIID.equals(Components.interfaces.nsIClassInfo) &&      
  493.         !aIID.equals(Components.interfaces.nsISupports))
  494.       throw Components.results.NS_ERROR_NO_INTERFACE;
  495.     return this;
  496.   }
  497. }
  498. /******************************************************************************
  499.  * XPCOM Functions for construction and registration
  500.  ******************************************************************************/
  501. var gModule = {
  502.   _firstTime: true,
  503.   registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
  504.   {
  505.     if (this._firstTime) {
  506.       this._firstTime = false;
  507.       throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  508.     };
  509.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  510.     aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
  511.   },
  512.  
  513.   unregisterSelf: function(aCompMgr, aLocation, aType)
  514.   {
  515.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  516.     aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);        
  517.   },
  518.   
  519.   getClassObject: function(aCompMgr, aCID, aIID)
  520.   {
  521.     if (!aIID.equals(Components.interfaces.nsIFactory))
  522.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  523.  
  524.     if (aCID.equals(CLASS_ID))
  525.       return gFactory;
  526.  
  527.     throw Components.results.NS_ERROR_NO_INTERFACE;
  528.   },
  529.  
  530.   canUnload: function(aCompMgr) { return true; }
  531. };
  532.  
  533. var gFactory = {
  534.   createInstance: function (aOuter, aIID)
  535.   {
  536.     if (aOuter != null)
  537.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  538.     return (new ffDisk()).QueryInterface(aIID);
  539.   }
  540. };
  541.  
  542. function NSGetModule(aCompMgr, aFileSpec) { return gModule; }